#pragma once
#include <iostream>
#include <string>
#include "Socket.hpp"
#include <memory>
#include <jsoncpp/json/json.h>
// 实现一个自定义的网络版的计算器
// tcp是面向字节流的
// 当读取的时候，可能读到一个完整的json请求，也可能读到半个？
// read->并不能保证读取到的报文的完整性！它只保证如果有数据就读上来。
// 当我们tcp中读取数据的时候，读取到的报文不完整，或者多读了，导致下一个报文不完整，这个问题叫做“粘包”问题！
// 所以需要自己实现协议的解析和序列化

// content_len jsonstring
// 50\r\n{"x":1,"y":2,"oper":"+"}\r\n
// 50
// {"x":1,"y":2,"oper":"+"}
using namespace SocketModule;

class Requese
{
public:
    Requese() {}
    Requese(int x, int y, char oper) : _x(x), _y(y), _oper(oper) {}

    std::string Serialize()
    {
        // json做序列化和反序列化处理
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;

        Json::FastWriter writer;
        std::string s = writer.write(root);
        return s;
    }

    bool Deserialize(std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool ok = reader.parse(in, root);
        if(ok)
        {
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _oper = root["oper"].asInt(); // ?
        }
        return ok;
    }
    ~Requese() {}

private:
    int _x;
    int _y;
    char _oper;
};

class Response
{
public:
    Response() {}
    Response(int result, int code) : _result(result), _code(code) {}
    std::string Serialize()
    {
        // json做序列化处理
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        Json::FastWriter writer;
        std::string s = writer.write(root);
        return s;
    }

    bool DeSerialize(std::string &in)
    {
        // json做反序列化处理
        Json::Value root;
        Json::Reader reader;
        bool ok = reader.parse(in, root);
        if(ok)
        {
            _result = root["result"].asInt();
            _code = root["code"].asInt();
        }
        return ok;
    }
    ~Response() {}

private:
    int _result; // 运算结果
    int _code;   // 0表示成功，1,2,3,4->不同的运算异常
};

const std::string sep = "\r\n";
// 实现一个自定义的网络版的计算器协议
// 
class Protocol
{
public:
    Protocol() {}
    std::string Encode(const std::string jsonstr)
    {
        std::string len = std::to_string(jsonstr.size());
        std::string package = len + sep + jsonstr + sep;
        return package;
    }

    // 1. 判断报文的完整性
    // 2. 如果包含至少一个完整请求，提取并移出它.
    bool Decode(std::string &buffer, std::string *package)
    {
        // 解析报文长度
        ssize_t pos = buffer.find(sep);
        if(pos == std::string::npos) return false;
        std::string package_len_str = buffer.substr(0, pos);
        int package_len_int = std::stoi(package_len_str);

        int target_len = package_len_str.size() + package_len_int + 2 * sep.size();
        if(buffer.size() < target_len) return false;

        // 解析报文内容
        *package = buffer.substr(pos + sep.size(), package_len_int);
        buffer.erase(0, target_len);

        return true;
    }
    void GetRequest(std::shared_ptr<Socket> &sock, InerAddr &client)
    {
        
    }
    ~Protocol() {}
private:
    // Response _req;
    // Response _resp;
};